<!DOCTYPE html>
<html>
<head>
  <title>Binary to Hexadecimal and Hexadecimal to Binary Conversion Practice</title>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
  <style type="text/css">
/*
COLORS:
GRAY: #5E6E7B;
BLACK: #13253D;
YELLOW: #FEFF9F;
RED: #E8515B;
GREEN: #51E853;
PURPLE: #554359;
*/
* { padding: 0px; margin: 0px; }
body {
  font-family: "Verdana", "Arial", sans-serif;
  font-size: 11px;
  text-align: auto;
  background: #000;
  color: #FEFF9F;
}
a {
  color: #FEFF9F;
}
#footer {
  text-align: center;
  padding: 5px;
  background: #554359;
}
#content {
  width: 800px;
  margin: 25px auto;
  text-align: left;
  background: #13253d;
}
h1 {
  font-size: 14px;
  text-align: center;
  background: #554359;
}
h2 {
  font-size: 13px;
}
h3 {
  font-size: 12px;
}
p, h1, h2, h3 {
  padding: 5px;
}
.notice {
  font-style: italic;
}
input {
  margin: 0px 5px;
}
textarea {
  margin: 10px;
  background: #5E6E7B;
  border: 0px;
  outline-width: 0px;
  padding: 5px;
  width: 760px;
  color: #FEFF9F;
  font-size: 12px;
}
input.text {
  margin: 10px;
  background: #5E6E7B;
  border: 0px;
  outline-width: 0px;
  padding: 5px;
  width: 760px;
  line-height: 150%;
  color: #FEFF9F;
  font-size: 12px;
}
#problemContainer {
  margin: 10px 0px;
}
#problemView {
  font-size: 20px;
  text-align: center;
  background: #554359;
}
.right, .wrong {
  display: inline-block;
  font-size: 13px;
  font-weight: bold;
  margin: 10px 0px;
  padding: 5px 15px;
}
.wrong {
  color: #E8515B;
}
.right {
  color: #51E853;
}
#solutionComparison {
  padding: 10px;
  background: #554359;
}
#problemView, .computedSolution, .userSolution, #solutionInput, textarea {
  font-family: "Courier", monospace;
}
.hidden {
  display: none !important;
}
  </style>
</head>
<body>
  <div id="content">
    <h1>Binary to Hexadecimal and Hexadecimal to Binary Conversion Practice</h1>
    <h2>Generate Problem:</h2>
    <form id="problemGenerator">
      <h3>Conversion Type</h3>
      <p>
        <input value="hexToBin" checked="checked" id="hexToBinary" type="radio" name="conversionType" /><label for="hexToBinary">Hex to Binary</label>
        <input value="binToHex" id="binaryToHex" type="radio" name="conversionType" /><label for="binaryToHex">Binary to Hex</label>
      </p>
      <h3>Number of Bytes</h3>
      <p>
        <input id="oneByte" value="1" checked="checked" type="radio" name="numBytes" /><label for="oneByte">One byte</label>
        <input id="twoBytes" value="2" type="radio" name="numBytes" /><label for="twoBytes">Two bytes</label>
        <input id="threeBytes" value="3" type="radio" name="numBytes" /><label for="threeBytes">Three bytes</label>
        <input id="fourBytes" value="4" type="radio" name="numBytes" /><label for="fourBytes">Four bytes</label>
      </p>
      <p><input type="submit" value="Generate Problem" name="Generate Problem" /></p>
    </form>
    <div id="problemContainer" class="hidden">
      <h2>Problem:</h2>
      <p id="problemView"></p>
    </div>
    <div id="workspaceContainer" class="hidden">
      <h2>Check Solution</h2>
      <form id="solutionChecker">
        <h3>Scratch Pad</h3>
        <p>
          <label class="notice">Scratch pad form is not checked, just a place to work out your solution</label><br />
          <textarea cols="100" rows="10" id="scratchPad"></textarea>
        </p>
        <p><a target="_blank" href="http://blog.apphackers.com/2010/02/26/binary-decimal-and-hexadecimal-conversion/">Conversion table</a></p>
        <h3>Your Solution</h3>
        <p>
          <input class="text" type="text" id="solutionInput" />
        </p>
        <p class="notice">Please separate bytes with a space and add leading 0's so that hex bytes always have two digits and binary bytes have eight.</p>
        <p><input type="submit" value="Check Solution" name="Check Solution" /></p>
      </form>
    </div>
    <div id="solutionContainer" class="hidden">
      <h2>Problem Solution</h2>
      <p id="solutionView"></p>
    </div>
    <div id="footer">
      Created by <a href="http://blog.apphackers.com">Apphacker</a> | <a href="http://code.google.com/p/computer-systems-book/source/checkout">Source</a>
    </div>
  </div>
  <script type="text/javascript">

var conv;
conv = { };

conv.init = function ( ) {
  conv.bindUI( );
};

conv.CONSTANTS = {
  CONVERSION_TYPE: {
    HEX_TO_BIN: "hexToBin",
    BIN_TO_HEX: "binToHex"
  }
};

conv.conversionType = null;

conv.generateProblem = function ( event ) {

  var numBytes;

  event.preventDefault( );
  event.stopPropagation( );

  conv.conversionType = null;
  if ( $( "#oneByte" ).get( 0 ).checked === true ) {
    numBytes = 1;
  } else if ( $( "#twoBytes" ).get( 0 ).checked === true ) {
    numBytes = 2;
  } else if ( $( "#threeBytes" ).get( 0 ).checked === true ) {
    numBytes = 3;
  } else {
    numBytes = 4;
  }
  if ( $( "#hexToBinary" ).get( 0 ).checked === true ) {
    conv.conversionType = conv.CONSTANTS.CONVERSION_TYPE.HEX_TO_BIN;
    conv.generateHexToBinProblem( numBytes );
  } else {
    conv.conversionType = conv.CONSTANTS.CONVERSION_TYPE.BIN_TO_HEX;
    conv.generateBinToHexProblem( numBytes );
  }
};

conv.problem = null;

conv.generateHexToBinProblem = function ( numBytes ) {
  conv.generateAnyProblem( numBytes, 16 );
};

conv.generateBinToHexProblem = function ( numBytes ) {
  conv.generateAnyProblem( numBytes, 2 );
};

conv.generateAnyProblem = function ( numBytes, base ) {

  var problemR, i, val, problemHTML;

  conv.clearWorkSpace( );
  problemR = [ ];
  problemHTML = [ ];
  for ( i = 0; i < numBytes; i++ ) {
    val = conv.getRandom( 0, 255 );
    problemR.push( val );
    val = val.toString( base );
    if ( base === 16 && val.length === 1 ) {
      val = "0" + val;
    } else if( base === 2 ) {
      while ( val.length < 8 ) {
        val = "0" + val;
      }
    }
    problemHTML.push( val )
  }
  conv.problem = problemR;
  $( "#problemView" ).html( problemHTML.join( " " ) );

};

conv.getRandom = function ( min, max ) {
  return Math.floor( Math.random( ) * ( max - min + 1 ) ) + min;
};

conv.getSolutionForProblem = function ( ) {

  var i, problemString, val, base;

  problemString = [ ];
  if ( conv.conversionType === conv.CONSTANTS.CONVERSION_TYPE.BIN_TO_HEX ) {
    base = 16;
  } else {
    base = 2;
  }
  for ( i = 0; i < conv.problem.length; i++ ) {
    val = conv.problem[ i ];
    val = val.toString( base );
    if ( base === 16 && val.length === 1 ) {
      val = "0" + val;
    } else if( base === 2 ) {
      while ( val.length < 8 ) {
        val = "0" + val;
      }
    }
    problemString.push( val )
  }
  return problemString.join( " " );

};

conv.clearWorkSpace = function ( ) {
  conv.problem = null;
  $( "#problemView" ).html( "" );
  $( "#workspaceContainer" ).removeClass( "hidden" );
  $( "#problemContainer" ).removeClass( "hidden" );
  $( "#solutionContainer" ).addClass( "hidden" );
  $( "#scratchPad" ).value = "";
  $( "#solutionInput" ).value = "";
  $( "#solutionView" ).html( "" );
};

conv.checkSolution = function ( event ) {

  var solutionString, userSolution, returnHTML;

  event.preventDefault( );
  event.stopPropagation( );

  returnHTML = [ ];
  solutionString = conv.getSolutionForProblem( );
  userSolution = $.trim( $( "#solutionInput" ).val( ) );
  if ( userSolution.toLowerCase( ) === solutionString.toLowerCase( ) ) {
    returnHTML.push( '<span class="right">Right answer.</span><br/>' );
  } else {
    returnHTML.push( '<span class="wrong">Wrong answer.</span><br/>' );
  }
  returnHTML.push( [
    '<div id="solutionComparison">',
      '<span class="computedSolution">',
      solutionString,
      ' &lt;-- computed solution.</span><br/>',
      '<span class="userSolution">',
      userSolution,
      ' &lt;-- your solution.</span>',
    '</div>'
  ].join( "" ) );
  $( "#solutionView" ).html( returnHTML.join( "" ) );
  $( "#solutionContainer" ).removeClass( "hidden" );
};

conv.bindUI = function ( ) {
  $( "#problemGenerator" ).bind( "submit", conv.generateProblem );
  $( "#solutionChecker" ).bind( "submit", conv.checkSolution );
};

$( document ).ready( conv.init );

  </script>
</body>
</html>
